 /**
 * 逻辑、功能相关描述: <br>
 *
 * @author 付湘辉  <br>
 * 编写日期：2008-8-29  <br>
 */
package com.ce.pms.charge.dao.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Query;

import com.ce.pms.base.dao.impl.PmsBaseDaoImpl;
import com.ce.pms.charge.dao.ISubAccountDao;
import com.ce.pms.charge.model.AbstractSubAccount;
import com.ce.pms.charge.model.ChargeAccountDomain;
import com.ce.pms.common.annotation.AssociatedBuildingQuery;
import com.ce.pms.common.model.SysrefcodeDO;
import com.ce.pms.common.util.SqlConfig;
import com.ce.pms.charge.vo.SubAccountBean;
import com.ce.pms.exception.BusinessException;

/**
 * 	名称: com.ce.pms.charge.dao.impl.SubAccountDaoImpl <br>
 *
 *
 * @author  付湘辉  <br>
 * Created on： 2008-8-29 <br>
 * @author <br>
 * update on： <br>
 * why: <br>
 */
public class SubAccountDaoImpl extends PmsBaseDaoImpl<AbstractSubAccount> implements ISubAccountDao {

	/**
	 * 功能描述:  根据银行ID 查询银行子帐户<br>且只查询产权房的银行帐号
	 * 返回的结果为一个list,每项为一个Object数组,1-房屋ID,2--房号,3--产权ID,4--银行账号,5--开户人,6--子帐户余额
	 * @param bankId
	 * @return
	 * Create author:yixianjian <br>
	 * Create on:2008-9-23  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public List findSubAccountByBankId(Long bankId){
		SqlConfig sqlConfig = new SqlConfig("BankCollectionSQL.xml");
		StringBuffer queryStr = new StringBuffer(sqlConfig.getSql("bankCollectionOut"));
		Query query = super.createSQLQuery(queryStr.toString(),new Object[]{bankId});
		return query.list();
	}
	/**
	 * 功能描述: 根据银行ID 查询银行子帐户<br>且只查询管理房的银行帐号 <br>
	 * 返回的结果为一个list,每项为一个Object数组,1-房屋ID,2--房号,3--产权ID,4--银行账号,5--开户人,6--子帐户余额
	 * @param bankId
	 * @return
	 * Create author:yixianjian <br>
	 * Create on:2008-12-4  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	@AssociatedBuildingQuery(alias = "house", beginStr = " AND ", endStr = " ", insertAfterPoint = "1=1",property4Building="building.keyword")
	public List findSubAccountWithVirtualHouseByBankId(Long bankId){
		SqlConfig sqlConfig = new SqlConfig("BankCollectionSQL.xml");
		StringBuffer queryStr = new StringBuffer(sqlConfig.getSql("bankCollectionOut_dummy"));
		Query query = super.createSQLQuery(queryStr.toString(),new Object[]{bankId});
		return query.list();
	}

	/**
	 * 功能描述:更新帐户余额。<br>
	 * @param subAccountIDBalances<br>
	 * Create author:罗军林<br>
	 * Create on:2008-9-27<br>
	 * Edit author:<br>
	 * Edit on:<br>
	 * Why:<br>
	 */
	public void updateSubAccountBalanceBatch(Map<Long,BigDecimal> subAccountIDBalances){
		String sql="UPDATE FEE_SUB_ACCOUNT SET BALANCE=? WHERE SUB_ACCOUNT_ID=?";
		List<Object[]> parameter=new ArrayList<Object[]>();
		for(Long subAccountId : subAccountIDBalances.keySet()){
			parameter.add(new Object[]{subAccountIDBalances.get(subAccountId),subAccountId});
		}
		executeSQLBatch(sql, parameter);
	}

	/**
	 * 功能描述:更新帐户余额, 余额 ＝ 原余额 + 给定金额<br>
	 * @param subAccountIDBalances<br>
	 * Create author:罗军林<br>
	 * Create on:2008-9-27<br>
	 * Edit author:<br>
	 * Edit on:<br>
	 * Why:<br>
	 */
	public void updateSubAccountBalanceBatchAdd(Map<Long,BigDecimal> subAccountIDBalances){
		String sql=" UPDATE FEE_SUB_ACCOUNT SET BALANCE=BALANCE+? WHERE SUB_ACCOUNT_ID=? ";
		List<Object[]> parameter=new ArrayList<Object[]>();
		for(Long subAccountId : subAccountIDBalances.keySet()){
			parameter.add(new Object[]{subAccountIDBalances.get(subAccountId),subAccountId});
		}
		executeSQLBatch(sql, parameter);
	}

	/**
	 * 功能描述:更新帐户余额为0。<br>
	 * @param subAccountIDBalances<br>
	 * Create author:罗军林<br>
	 * Create on:2008-9-27<br>
	 * Edit author:<br>
	 * Edit on:<br>
	 * Why:<br>
	 */
	public void updateSubAccountBalanceBatch(List<Long> subAccountIds){
		String sql=" UPDATE FEE_SUB_ACCOUNT SET BALANCE=0.0 WHERE SUB_ACCOUNT_ID=? ";
		List<Object[]> parameter=new ArrayList<Object[]>();
		for(Long subAccountId : subAccountIds){
			parameter.add(new Object[]{subAccountId});
		}
		executeSQLBatch(sql, parameter);
	}

	/**
	 * 功能描述:更新帐户余额。余额＝原余额－给定金额<br>
	 * @param subAccountIDBalances<br>
	 * Create author:罗军林<br>
	 * Create on:2008-9-27<br>
	 * Edit author:<br>
	 * Edit on:<br>
	 * Why:<br>
	 */
	public void updateSubAccountBalanceBatchSub(Map<Long,BigDecimal> subAccountIDBalances){
		String sql="UPDATE FEE_SUB_ACCOUNT SET BALANCE=BALANCE-? WHERE SUB_ACCOUNT_ID=?";
		List<Object[]> parameter=new ArrayList<Object[]>();
		for(Long subAccountId : subAccountIDBalances.keySet()){
			parameter.add(new Object[]{subAccountIDBalances.get(subAccountId),subAccountId});
		}
		executeSQLBatch(sql, parameter);
	}

	/**
	 * 功能描述:查询所有的子帐户。KEY 房号ID value SubAccountBean对象<br>
	 * @return<br>
	 * Create author:罗军林<br>
	 * Create on:2008-10-7<br>
	 * Edit author:<br>
	 * Edit on:<br>
	 * Why:<br>
	 */
	public Map<Long,SubAccountBean> getAllSubAccount(){
		String hql="SELECT new com.ce.pms.charge.vo.SubAccountBean(sub.account.house.keyword,sub.subAccountId,sub.lockState) FROM ChargeAccountDomain sub WHERE sub.account.isActive='1'";
		Query query=createQuery(hql, null);
		List<SubAccountBean> list=query.list();
		Map<Long,SubAccountBean> result=new HashMap<Long, SubAccountBean>();
		for(SubAccountBean item : list){
			result.put(item.getHouseId(), item);
		}

		return result;
	}

	/**
	 * 方法描述: 根据房间ID查询收费子账户
	 * @author 胡煦
	 * Create on:2008-10-9
	 * @param hosueId
	 * @return ChargeAccountDomain
	 * Edit author:
	 * Edit on:
	 * 修改原因：
	 */
	public ChargeAccountDomain getChargeAccountDoBy(Long hosueId){
		String queryStr = "from ChargeAccountDomain cd where cd.account.house.id = ?";
		Query query = createQuery(queryStr, hosueId);
		return (ChargeAccountDomain) query.list().get(0);
	}

	/**
	 * 功能描述: 更新指定子账户的锁定状态 <br>
	 * @param subAccountId 指定子账户id
	 * @param lockState 新状态
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-10-13  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public void updateLockState(final Long subAccountId,final String lockState){
		this.checkLockStateValue(lockState);
		AbstractSubAccount domain = super.findById(subAccountId);
		domain.setLockState(lockState);
		super.updateObject(domain);
	}

	/**
	 * 功能描述: 查询指定id的子账户锁定状态 <br>
	 * @param subAccountId
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-10-20  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public String queryLockStateById(final Long subAccountId){
		AbstractSubAccount domain = super.findById(subAccountId);
		return domain.getLockState();
	}

	/**
	 * 功能描述:返回指定房号ID列表中被锁定借方物业帐户的房号列表。如1-2a,1-2b<br>
	 * @param houseIds
	 * @return<br>
	 * Create author:罗军林<br>
	 * Create on:2008-10-23<br>
	 * Edit author:<br>
	 * Edit on:<br>
	 * Why:<br>
	 */
	public String queryLockDdebitChargeSubAccount(String houseIds){
		StringBuffer  sql = new StringBuffer();
		sql.append("SELECT   GROUP_CONCAT(H.HOUSE_NUMBER),");
		sql.append("          1 AS SEQ");
		sql.append(" FROM     FEE_SUB_ACCOUNT SUB");
		sql.append("          INNER JOIN FEE_ACCOUNT ACC");
		sql.append("            ON SUB.ACCOUNT_ID = ACC.ACCOUNT_ID");
		sql.append("          INNER JOIN HM_HOUSE H");
		sql.append("            ON H.HOUSE_ID = ACC.HOUSE_ID");
		sql.append(" WHERE    ACC.IS_ACTIVE = '1'");
		sql.append("          AND SUB.ACCOUNT_TYPE='001'");
		sql.append("          AND (SUB.LOCK_STATE = '10' OR SUB.LOCK_STATE = '11')");
		sql.append(" 		  AND H.HOUSE_ID IN(").append(houseIds).append(") ");
		sql.append(" GROUP BY SEQ");
		Query query=createSQLQuery(sql.toString(), null);
		Object[] result=(Object[])query.uniqueResult();
		return result==null ? null : (String)result[0];
	}

	/**
	 * 功能描述: 检查锁定状态的值是否合法，合法值为：00,01,10,11 <br>
	 * @param lockState
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-10-13  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private void checkLockStateValue(final String lockState){
		if (!(SysrefcodeDO.FEE_ACCOUNT_LOCK_STATE_NOLOCK.equals(lockState)
				|| SysrefcodeDO.FEE_ACCOUNT_LOCK_STATE_LOCK_DEBIT.equals(lockState)
				|| SysrefcodeDO.FEE_ACCOUNT_LOCK_STATE_LOCK_CREDIT.equals(lockState)
				|| SysrefcodeDO.FEE_ACCOUNT_LOCK_STATE_LOCK_ALL.equals(lockState))) {
			throw new BusinessException("charge:charge_subaccount_lockvalue_illegal_exception",
					BusinessException.WARNING);
		}
	}

}
